package NextClass.Native;

import app.boot.BaseFunction;
import build.Bin.Function;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import expression.MathExpression;
import expression.StringExpression;
import vm.runtime.NextVMRuntime;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;


class HttpRun implements HttpHandler {

    private String extraData = null;
    private NextVMRuntime nextVMRuntime = null;

    /**
     * 将HttpExchange中的请求头转换为字符串。
     *
     * @param exchange HttpExchange对象，从中获取请求头
     * @return 包含所有请求头的字符串
     */
    public static String getHeadersAsString(HttpExchange exchange) throws IOException {
        Map<String, List<String>> headers = exchange.getRequestHeaders();
        StringBuilder headersString = new StringBuilder();

        for (Map.Entry<String, List<String>> header : headers.entrySet()) {
            headersString.append(header.getKey()).append(": ");
            for (String value : header.getValue()) {
                headersString.append(value).append(", ");
            }
            // Remove the last comma and space
            headersString.setLength(headersString.length() - 2);
            headersString.append("\n");
        }

        return headersString.toString();
    }

    public static byte[] getBodyAsByteArray(HttpExchange exchange) throws IOException {
        InputStream is = exchange.getRequestBody();
        ReadableByteChannel channel = Channels.newChannel(is);
        ByteBuffer buffer = ByteBuffer.allocate(1024); // 可以调整缓冲区大小
        int bytesRead;
        int totalBytesRead = 0;

        // 循环读取直到没有更多数据
        while ((bytesRead = channel.read(buffer)) != -1) {
            totalBytesRead += bytesRead;
            buffer.clear(); // 清除缓冲区，准备下一次读取
        }
        return buffer.array();
    }

    public HttpRun(NextVMRuntime nextVMRuntime,String extraData) {
        this.extraData = extraData;
        this.nextVMRuntime = nextVMRuntime;
    }


    @Override
    public void handle(HttpExchange httpExchange) throws IOException{
        try {
            String URL = java.net.URLDecoder.decode(httpExchange.getRequestURI().toString());
            String head = getHeadersAsString(httpExchange);
            byte[] bytes = getBodyAsByteArray(httpExchange);
            OutputStream outputStream = httpExchange.getResponseBody();

            String pointer_1 = String.valueOf(BaseFunction.getRandomLong());
            String pointer_2 = String.valueOf(BaseFunction.getRandomLong());
            String pointer_3 = String.valueOf(BaseFunction.getRandomLong());
            String pointer_4 = String.valueOf(BaseFunction.getRandomLong());

            nextVMRuntime.values.put(pointer_1 , URL);
            nextVMRuntime.values.put(pointer_2 , head);
            nextVMRuntime.values.put(pointer_3 , bytes);
            nextVMRuntime.values.put(pointer_4 , outputStream);
            String[] Inputs = {pointer_1 , pointer_2 , pointer_3 , pointer_4};

            NextVMRuntime fn = NextVMRuntime.getFunctionFromRuntime(extraData,nextVMRuntime);
            Function.putInputFunction(extraData,fn,nextVMRuntime,Inputs);

            nextVMRuntime.values.remove(pointer_1);
            nextVMRuntime.values.remove(pointer_2);
            nextVMRuntime.values.remove(pointer_3);
            nextVMRuntime.values.remove(pointer_4);

            httpExchange.sendResponseHeaders(200,0);
            fn.run();
        }
        catch (Exception e) {
            e.printStackTrace();
            httpExchange.sendResponseHeaders(500 , 0);
            httpExchange.close();
        }
    }
}

public class HttpService {
    public static String[] ClassMethods = {
            "URL",
            "start",
            "thread"
    };
    public static Object run(String Invoke, Object object,NextVMRuntime nextVMRuntime, Object... objects) throws Exception{
        HttpServer httpServer = (HttpServer) object;

        if (Invoke.equals("URL")) {
            String URL = (String) objects[0];
            String FuncName = (String) objects[1];

            httpServer.createContext(URL , new HttpRun(nextVMRuntime,FuncName));
            return null;
        }
        else if (Invoke.equals("thread")) {
            int thread = (int) objects[0];
            httpServer.setExecutor(Executors.newFixedThreadPool(thread));
            return null;
        }
        else if (Invoke.equals("start")) {
            httpServer.start();
            return null;
        }
        else {
            return null;
        }
    }
}
